package com.tutu.mybatis.dynamic.datasource.aop;

import com.tutu.mybatis.dynamic.datasource.config.DynamicRoutingDataSourceHolder;
import com.tutu.mybatis.dynamic.datasource.util.UserInfoHolder;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

import static com.tutu.mybatis.dynamic.datasource.listener.CollectDynamicAnnotationListener.DYNAMIC_DATASOURCE_SERVICE_CACHE;

/**
 * 数据源切换的切面
 *
 * @author 丘友垚
 * @version 1.0
 * @date 2020/9/23 20:17
 */
@Component
@Aspect
@Order(1)
public class DataSourceAspect {

    private static final Logger logger = LoggerFactory.getLogger(DataSourceAspect.class);

    @Before("pointCut()")
    public void before(JoinPoint joinPoint) {
        //获取目标类上是否有DynamicDatasource注解
        Object target = joinPoint.getTarget();
        logger.info("target --> {}", target);
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        //如果service没有标记注解,就切换到主库
        boolean hasDynamicDatasource = DYNAMIC_DATASOURCE_SERVICE_CACHE.contains(target.getClass().getName()) ||
                DYNAMIC_DATASOURCE_SERVICE_CACHE.contains(target.getClass().getName() + "#" + method);
        if (!hasDynamicDatasource) {
            DynamicRoutingDataSourceHolder.removeKey();
            return;
        }
        long userId = UserInfoHolder.getUserId();
        logger.info("current login user's id:{}", userId);
        String datasourceKey = DynamicRoutingDataSourceHolder.KEY_PREFIX + userId;
        String currentKey = DynamicRoutingDataSourceHolder.getKey();
        //key相同就不需要切换了
        if (datasourceKey.equals(currentKey)) {
            return;
        }
        DynamicRoutingDataSourceHolder.setKey(datasourceKey);
        logger.info("datasource key set success: {}", datasourceKey);
    }

    @Pointcut("this(com.baomidou.mybatisplus.extension.service.IService)")
    public void pointCut() {
    }

    @After("pointCut()")
    public void after() {
        String key = DynamicRoutingDataSourceHolder.getKey();
        DynamicRoutingDataSourceHolder.removeKey();
        UserInfoHolder.remove();
        logger.info("datasource key:{} remove success", key);
    }

}
